﻿using MediatR;

using Microsoft.EntityFrameworkCore;

using Tszy.Unlimited.Base.Exceptions;
using Tszy.Unlimited.Base.Infrastructure.Logging;
using Tszy.Unlimited.Base.Models;

namespace Tszy.Unlimited.Base.Features;

/// <summary>
/// 功能封装-请求信息。
/// </summary>
/// <typeparam name="TRequest">请求数据。</typeparam>
/// <typeparam name="TResponse">响应数据。</typeparam>
public abstract class FunctionRecordFeatureHandler<TRequest, TResponse> : IRequestHandler<TRequest, ResponseResult<TResponse>>
    where TRequest : FunctionRecordFeatureRequest<TResponse>
{
    /// <summary>
    /// 是否使用事务。
    /// </summary>
    protected bool transaction = true;

    /// <summary>
    /// 响应数据。
    /// </summary>
    protected TResponse? response = default;

    /// <summary>
    /// 初始化。
    /// </summary>
    /// <param name="transaction">是否启用事务。</param>
    protected FunctionRecordFeatureHandler(bool transaction = true)
    {
        this.transaction = transaction;
    }

    /// <summary>
    /// 验证。
    /// </summary>
    protected virtual async Task OnLoadAsync(TRequest request, CancellationToken cancellationToken)
    {
        await Task.CompletedTask;
    }

    /// <summary>
    /// 验证。
    /// </summary>
    protected virtual async Task OnValidateAsync(TRequest request, CancellationToken cancellationToken)
    {
        await Task.CompletedTask;
    }

    /// <summary>
    /// 实际处理方法。
    /// </summary>
    protected virtual async Task OnHandleAsync(TRequest request, CancellationToken cancellationToken)
    {
        await OnExecuteAsync(request, cancellationToken);
    }

    /// <summary>
    /// 实际处理方法。
    /// </summary>
    protected abstract Task OnExecuteAsync(TRequest request, CancellationToken cancellationToken);

    /// <summary>
    /// 处理。
    /// </summary>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public virtual async Task<ResponseResult<TResponse>> Handle(TRequest request, CancellationToken cancellationToken)
    {
        try
        {
            await OnLoadAsync(request, cancellationToken);
            await OnValidateAsync(request, cancellationToken);
            await OnHandleAsync(request, cancellationToken);

            if (response == null)
                return ResponseResult<TResponse>.Success();

            return ResponseResult<TResponse>.Success(response);
        }
        catch (MainApplicationException exception)
        {
            if (response == null)
                return ResponseResult<TResponse>.Error(exception.Message, exception.ErrorCode);

            return ResponseResult<TResponse>.Error(exception.Message, response, exception.ErrorCode);
        }
        catch (DbUpdateException exception)
        {
            TszyLogger.Instance.Fatal($"[{GetType().Name}]执行过程中出现异常", exception);

            if (exception.InnerException != null)
                return ResponseResult<TResponse>.Error("服务暂时不可用，请稍后再试[-2]");

            return ResponseResult<TResponse>.Error("服务暂时不可用，请稍后再试[-1]");
        }
        catch (Exception exception)
        {
            TszyLogger.Instance.Fatal($"[{GetType().Name}]执行过程中出现异常", exception);
            return ResponseResult<TResponse>.Error("服务暂时不可用，请稍后再试[-3]");
        }
    }
}